package com.yohann.user_service.service.impl;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yohann.base.exception.IEnglishException;
import com.yohann.user_service.entity.User;
import com.yohann.user_service.entity.vo.RegisterVo;
import com.yohann.user_service.mapper.UserMapper;
import com.yohann.user_service.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yohann.utils.jwt.JwtUtils;
import com.yohann.utils.md5.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author Yohann
 * @since 2020-10-29
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    RedisTemplate<String, String> redisTemplate;

    /**
     * 用户登录
     *
     * @param user 账号密码
     * @return token
     */
    @Override
    public String login(User user) {
        return getToken(user, false);
    }

    /**
     * 用户注册
     *
     * @param registerVo 注册信息
     */
    @Override
    public void register(RegisterVo registerVo) {
        //验证码
        String code = registerVo.getCode();
        //手机号
        String phone = registerVo.getPhone();
        //昵称
        String nickName = registerVo.getNickname();
        //密码
        String password = registerVo.getPassword();
        //头像
        String avatar = registerVo.getAvatar();

        //通过redis验证验证码
        if (!code.equals(redisTemplate.opsForValue().get(phone))) {
            throw new IEnglishException(20001, "验证码错误");
        }

        //验证手机号是否已注册
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(User::getPhone, registerVo.getPhone());
        if (baseMapper.selectCount(wrapper) > 0) {
            throw new IEnglishException(20001, "该手机号已注册！");
        }

        User user = new User();
        user.setPhone(phone)
                .setNickname(nickName)
                .setPassword(MD5.encode(password))
                .setAvatar(Objects.isNull(avatar) ? "https://rice-college.oss-cn-shenzhen.aliyuncs.com/2020/08/07/89b8b90598be48e1ba3efaeab46b3b96default.jpg" : avatar);

        baseMapper.insert(user);
    }

    /**
     * 管理员登录
     *
     * @param user 账号密码
     * @return token
     */
    @Override
    public String loginSuper(User user) {
        return getToken(user, true);
    }

    /**
     * 用户登录
     *
     * @param user 登录信息
     * @return token
     */
    private String getToken(User user, boolean admin) {
        //获取手机号、密码
        String phone = user.getPhone();
        String password = user.getPassword();

        //非管理员判断手机号
        if (!admin) {
            if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(password)) {
                throw new IEnglishException(20001, "登录失败！");
            }
        }

        //判断手机号、密码是否正确 以及禁用状态是否为false
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(User::getPassword, MD5.encode(user.getPassword()))
                .eq(User::getDisabled, false);

        if (admin) {
            //管理员使用用户名登录
            queryWrapper.eq(User::getNickname, user.getNickname())
                    .eq(User::getAdministrator, true);
        } else {
            queryWrapper.eq(User::getPhone, phone);
        }
        User userInfo = baseMapper.selectOne(queryWrapper);

        if (userInfo == null) {
            throw new IEnglishException(20001, "登录失败！");
        }

        //登录成功 生成token
        return JwtUtils.getJwtToken(userInfo.getId().toString(), userInfo.getNickname());
    }

    /**
     * 分页查询用户信息
     *
     * @param current 起始位置
     * @param limit   结束位置
     * @param user    查询条件
     * @return 结果集
     */
    @Override
    public Map<String, Object> pageQueryUser(int current, int limit, User user) {
        //将起始位置、结束位置存入map
        Page<User> page = new Page<>(current, limit);

        //判断是否存在查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        if (user != null) {
            //查询条件
            if (!StringUtils.isEmpty(user.getNickname())) {
                queryWrapper.like(User::getNickname, user.getNickname());
            }
            if (!StringUtils.isEmpty(user.getPhone())) {
                queryWrapper.like(User::getPhone, user.getPhone());
            }
            if (!StringUtils.isEmpty(user.getGender())) {
                queryWrapper.eq(User::getGender, user.getGender());
            }
            if (!StringUtils.isEmpty(user.getDisabled())) {
                queryWrapper.eq(User::getDisabled, user.getDisabled());
            }
        }

        //查询的列
        queryWrapper.select(
                User::getId,
                User::getPhone,
                User::getNickname,
                User::getAge,
                User::getGender,
                User::getAvatar,
                User::getDisabled,
                User::getAdministrator);

        //通过分页 查询用户信息
        IPage<User> userPage = baseMapper.selectPage(page, queryWrapper);

        //将结果存入map中并返回
        Map<String, Object> map = new HashMap<>();
        map.put("total", userPage.getTotal());
        map.put("rows", userPage.getRecords());

        return map;
    }

    /**
     * 登录返回id
     */
    @Override
    public Integer login(String phone, String password) {
        //判断手机号、密码是否正确 以及禁用状态是否为false
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPassword, MD5.encode(password))
                .eq(User::getDisabled, false);

        queryWrapper.eq(User::getPhone, phone);
        User userInfo = baseMapper.selectOne(queryWrapper);

        if (userInfo == null) {
            throw new IEnglishException(20001, "登录失败！");
        }

        return userInfo.getId();
    }
}
